using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace AgileCode
{
    [TestClass]
    public class Feature_request_1
    {
        [TestMethod]
        public void Write_a_program_that_copies_characters_from_the_keyboard_to_the_printer()
        {
            Copier.Copy();
        }

        public static class Copier
        {
            public static void Copy()
            {
                char c;
                while (char.ToLower(c = Keyboard.Read()) != 'x')
                    Printer.Write(c);
            }
        }
    }

    [TestClass]
    public class Feature_request_2
    {
        [TestMethod]
        public void Should_now_also_be_able_to_read_from_the_paper_tape_reader()
        {
            Copier.ptFlag = true;
            Copier.Copy();
        }

        public static class Copier
        {
            public static bool ptFlag;

            public static void Copy()
            {
                char c;
                while (char.ToLower(c = (ptFlag ? PaperTape.Read() : Keyboard.Read())) != 'x')
                    Printer.Write(c);
            }
        }
    }

    [TestClass]
    public class Feature_request_3
    {
        [TestMethod]
        public void Should_now_also_be_able_to_output_to_the_pape_tape_punch()
        {
            Copier.ptFlag = true;
            Copier.punchFlag = true;
            Copier.Copy();
        }

        public static class Copier
        {
            public static bool ptFlag;
            public static bool punchFlag;

            public static void Copy()
            {
                char c;
                while (char.ToLower(c = (ptFlag ? PaperTape.Read() : Keyboard.Read())) != 'x')
                {
                    if (punchFlag)
                        PaperTape.Punch(c);
                    else
                        Printer.Write(c);
                }
            }
        }
    }

    [TestClass]
    public class Feature_request_n
    {
        [TestMethod]
        public void Getting_crazy_now()
        {
            Copier.ptFlag = true;
            Copier.punchFlag = true;
            Copier.Copy();
        }

        public static class Copier
        {
            // input fields (only set one)
            public static bool ptFlag;
            public static bool fileInFlag;
            public static string fileInName; // only set if 'fileInFlag' is set

            // output fields (only set one)
            public static bool punchFlag;
            public static bool fileOutFlag;
            public static string fileOutName; // only set if 'fileOutFlag' is set

            public static void Copy()
            {
                // ... you get the idea
            }
        }
    }

    [TestClass]
    public class First_enhancement_request_revisited
    {
        [TestMethod]
        public void Done_the_agile_way()
        {
            Copier.Read = PaperTape.Read;
            Copier.Write = PaperTape.Punch;
            Copier.Copy();
        }

        public static class Copier
        {
            public static Func<char> Read = Keyboard.Read;
            public static Action<char> Write = Printer.Write;

            public static void Copy()
            {
                char c;
                while (char.ToLower(c = Read()) != 'x')
                    Write(c);
            }
        }
    }
}